package com.houkunlin.wake.lan.host;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.houkunlin.system.applog.starter.AppLog;
import com.houkunlin.system.common.exception.BusinessException;
import com.houkunlin.wake.lan.cmd.Computer;
import com.houkunlin.wake.lan.utils.WakeOnLan;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Controller：主机信息
 *
 * @author HouKunLin
 */
@Api(tags = "主机信息")
@RestController
@RequestMapping("host-info")
@AllArgsConstructor
public class HostInfoController {
    private final HostInfoService hostInfoService;
    private final HostInfoTransform hostInfoTransform;

    /**
     * 获取全部的 <strong>主机信息</strong> 列表
     *
     * @param page  分页参数信息
     * @param query 查询信息
     */
    @ApiOperation("主机信息-列表（不分页）")
    @GetMapping("all")
    public List<HostInfoVo> listAll(@PageableDefault IPage<HostInfo> page, HostInfoQuery query) {
        final List<HostInfo> list = query.query(hostInfoService, page).list();
        return list.stream().map(hostInfoTransform::toVo).collect(Collectors.toList());
    }

    /**
     * 分页获取 <strong>主机信息</strong> 列表
     *
     * @param page  分页参数信息
     * @param query 查询信息
     */
    @ApiOperation("主机信息-列表（分页）")
    @GetMapping
    public Object listPage(@PageableDefault IPage<HostInfo> page, HostInfoQuery query) {
        return query.lambdaQuery(hostInfoService).page(page).convert(hostInfoTransform::toVo);
    }

    /**
     * 获取一个 <strong>主机信息</strong>
     *
     * @param id 主键ID
     */
    @ApiOperation("主机信息-详细信息")
    @ApiImplicitParam(name = "id", value = "主键", required = true, paramType = "path", dataTypeClass = String.class)
    @GetMapping("{id}")
    public HostInfo info(@PathVariable String id) {
        return hostInfoService.getById(id);
    }

    /**
     * 获取一个 <strong>主机信息</strong>
     *
     * @param id 主键ID
     */
    @ApiOperation("主机信息-启动主机")
    @ApiImplicitParam(name = "id", value = "主键", required = true, paramType = "query", dataTypeClass = String.class)
    @PostMapping("startUp")
    public Object startUp(String id) {
        final HostInfo info = hostInfoService.getById(id);
        if (info == null) {
            throw new BusinessException("找不到资源");
        }
        if (!StringUtils.hasText(info.getMac())) {
            throw new BusinessException("该资源没有 MAC 地址");
        }
        final Computer.ComputerBuilder builder = Computer.builder().mac(info.getMac());
        if (StringUtils.hasText(info.getGateway())) {
            builder.gateway(info.getGateway());
        } else {
            builder.gateway("255.255.255.255");
        }
        final Integer port = info.getPort();
        if (port != null && port > 0 && port < 65536) {
            builder.port(port);
        } else {
            builder.port(9);
        }

        WakeOnLan.bootstrap(builder.build());

        return "OK";
    }

    /**
     * 添加一个 <strong>主机信息</strong>
     *
     * @param form 主机信息
     */
    @ApiOperation("主机信息-保存信息")
    @AppLog("#{#form.id?.isEmpty() == true ? '新增' : '修改'}主机信息：#{#form.id} (ID-#{result})")
    @PostMapping
    public String saveHostInfo(@Valid @RequestBody HostInfoForm form) {
        final HostInfo hostInfo = hostInfoService.saveHostInfo(form);
        return hostInfo.getId();
    }

    /**
     * 删除多个 <strong>主机信息</strong>
     *
     * @param ids 主键ID列表
     */
    @ApiOperation("主机信息-删除信息")
    @ApiImplicitParam(name = "ids", value = "主键数组", allowMultiple = true, required = true, paramType = "body", dataTypeClass = String[].class)
    @AppLog("删除主机信息：#{result}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    @DeleteMapping
    public String deleteHostInfo(@RequestBody Set<String> ids) {
        return hostInfoService.deleteHostInfo(ids);
    }

}
